package com.example.invoker.utils;

import com.google.common.collect.Lists;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class ZonedDateUtil {
    public static final Logger logger = LoggerFactory.getLogger(ZonedDateUtil.class);

    public static final String formatterWithTimeZone = "yyyy-MM-dd'T'HH:mm:ssZ";
    public static final String formatterIntStr = "yyyyMMddHHmmss";
    public static final String dayFormatterStr = "yyyy-MM-dd";
    public static final String dayFormatterInt = "yyyyMMdd";
    public static final String formatterDateTimeStr = "yyyy-MM-dd HH:mm:ss";
    public static final String INT_DATE_PATTERN = "yyyyMMdd";
    public static final String INT_YEAR_MONTH_PATTERN = "yyyy-MM";

    public static final String TIMEZONE_US_PACIFIC = "US/Pacific";
    public static final String TIMEZONE_ASIN_SHANGHAI = "Asia/Shanghai";
    public static final String TIMEZONE_UTC = "UTC";

    public static final String HOUR_FORMATTER_STR = "yyyyMMddHH";

    public static ZonedDateTime usCurrentTime() {
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of(TIMEZONE_US_PACIFIC));
        return now;
    }

    public static String formatDate(ZonedDateTime zonedDateTime, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return zonedDateTime.format(formatter);
    }

    public static String formatDate(Date date, String pattern, String zoneId) {
        ZonedDateTime zonedDateTime = convertDate(date, zoneId);
        return formatDate(zonedDateTime, pattern);
    }

    public static ZonedDateTime convertDate(Date date, String zoneId) {
        Instant instant = date.toInstant();
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.of(zoneId));
        return zonedDateTime;
    }

    public static Date convertToDate(ZonedDateTime zonedDateTime) {
        return Date.from(zonedDateTime.toInstant());
    }

    public static String convertDateFormat(String strDate, String patternCurrent, String patternDes) {
        LocalDate localDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern(patternCurrent));
        String format = localDate.format(DateTimeFormatter.ofPattern(patternDes));
        return format;
    }

    public static Long getDateLocal(Date date, String zoneId) {
        ZonedDateTime zonedDateTime = convertDate(date, zoneId);
        String format = DateTimeFormatter.ofPattern(formatterIntStr).format(zonedDateTime);
        Long dateLocalInt = Long.valueOf(format);
        return dateLocalInt;
    }

    public static ZonedDateTime convertTimestamp(long ts){
        Timestamp timestamp = new Timestamp(ts);
        return timestamp.toInstant().atZone(ZoneId.systemDefault());
    }

    public static Timestamp convertZoneDateTime(ZonedDateTime zonedDateTime){
        return Timestamp.from(zonedDateTime.toInstant());
    }

    public static long intervalInAbsHours(ZonedDateTime zonedDateTime, ZonedDateTime compareTo){
        return Duration.between(zonedDateTime, compareTo).abs().toHours();
    }

    public static long intervalInAbsMinutes(ZonedDateTime zonedDateTime, ZonedDateTime compareTo) {
        return Duration.between(zonedDateTime, compareTo).abs().toMinutes();
    }

    public static ZonedDateTime toStartOfTheDay(String date, String zoneId) {
        LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate,LocalTime.MIDNIGHT,ZoneId.of(zoneId));
        return zonedDateTime;
    }

    public static ZonedDateTime toEndOfTheDay(String date, String zoneId) {
        LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate,LocalTime.MAX,ZoneId.of(zoneId));
        return zonedDateTime;
    }

    public static ZonedDateTime today(String zoneId) {
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of(zoneId));
        return ZonedDateTime.of(now.toLocalDate(), LocalTime.MIDNIGHT, ZoneId.of(zoneId));
    }

    public static String todayInYMD(String zoneId){
        ZonedDateTime now = today(zoneId);
        return now.format(DateTimeFormatter.ISO_LOCAL_DATE);
    }

    public static Integer todayInt(String zoneId) {
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of(zoneId));
        Integer today = Integer.valueOf( now.format(DateTimeFormatter.ofPattern("yyyyMMdd")) );
        return today;
    }

    public static LocalDate instantToLocalDate(Long epochMilli, String zoneIdStr) {
        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.of(zoneIdStr)).toLocalDate();
    }

    public static LocalDate unzonedDateStrToInstant(String unzonedDateStr) {
        return LocalDate.parse(unzonedDateStr, DateTimeFormatter.ofPattern(dayFormatterStr));
    }

    public static ZonedDateTime todayOfZonedDate(ZonedDateTime date, String zoneId) {
        return ZonedDateTime.of(date.getYear(),date.getMonthValue(),date.getDayOfMonth(),
                0,0,0,0,ZoneId.of(zoneId));
    }

    public static ZonedDateTime todayOfDate(Date date, String zoneId) {
        ZonedDateTime zoneDate = ZonedDateUtil.convertDate(date, zoneId);
        return ZonedDateTime.of(zoneDate.getYear(),zoneDate.getMonthValue(),zoneDate.getDayOfMonth(),
                0,0,0,0,ZoneId.of(zoneId));
    }

    public static ZonedDateTime getZonedDateTime(String date, String zoneId) {
        LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        return ZonedDateTime.of(localDateTime, ZoneId.of(zoneId));
    }

    /**
     * 将形如 "yyyy-MM-dd" 转换成 ZonedDateTime类型
     * @param zoneId
     * @param dateStr
     * @return
     */
    public static ZonedDateTime convertDateStrToZonedDateTime(String zoneId, String dateStr) {
        dateStr = new StringBuilder(dateStr.trim())
                .append("T00:00:00").toString();
        return ZonedDateUtil.getZonedDateTime(dateStr, zoneId);
    }

    /**
     * 将形如 "yyyy-MM-dd HH:mm:ss" 转换成 ZonedDateTime类型
     * @param zoneId
     * @param dateStr
     * @return
     */
    public static ZonedDateTime convertDateTimeStrToDate(String zoneId, String dateStr) {
        dateStr = dateStr.trim().replace(" ", "T");
        ZonedDateTime zonedDateTime = ZonedDateUtil.getZonedDateTime(dateStr, zoneId);
        return zonedDateTime;
    }

    public static Integer toYMD(ZonedDateTime zonedDateTime) {
        return Integer.valueOf(DateTimeFormatter.ofPattern(ZonedDateUtil.dayFormatterInt).format(zonedDateTime));
    }

    public static String convertDateToStrByZone(Date date, String pattern, String zoneId) {
        if (date == null) {
            return "";
        }
        ZonedDateTime dateTime = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of(zoneId));
        return DateTimeFormatter.ofPattern(pattern).format(dateTime);
    }

    public static Integer currentAsiaDate() {
        String dateStr = convertDateToStrByZone(new Date(), dayFormatterInt, TIMEZONE_ASIN_SHANGHAI);
        return Integer.valueOf(dateStr);
    }

    /**
     * 将形如 "yyyyMMdd" 转换成 ZonedDateTime类型
     * @param dateInt
     * @param zoneId
     * @return yyyy-MM-dd 00:00:00
     */
    public static ZonedDateTime convertDateIntToZoneDate(Integer dateInt, String zoneId) {
        String dateStr = String.valueOf(dateInt);
        String[] arrays = {dateStr.substring(0,4), dateStr.substring(4,6), dateStr.substring(6,8)};
        dateStr = StringUtils.join(arrays, '-');
        return ZonedDateUtil.convertDateStrToZonedDateTime(zoneId, dateStr);
    }

    public static String getCurrentDateStrOfZoneId(String zoneId, String pattern) {
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of(zoneId));
        LocalDateTime localDateTime = zonedDateTime.toLocalDateTime().withNano(0);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return localDateTime.format(dateTimeFormatter);
    }

    public static Date convertToDate(Integer date, ZoneId zoneId, String pattern) {
        return convertToDate(date, zoneId, pattern, LocalTime.MIN);
    }

    public static Integer convertToIntDate(Date date, ZoneId zoneId) {
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), zoneId);
        LocalDate localDate = zonedDateTime.toLocalDate();
        String intDateStr = localDate.format(DateTimeFormatter.ofPattern(INT_DATE_PATTERN));
        return Integer.valueOf(intDateStr);
    }

    public static Integer convertToIntDate(String dateStrWithOutZone) {
        LocalDate localDate = LocalDate.parse(dateStrWithOutZone, DateTimeFormatter.ISO_LOCAL_DATE);
        String dateStr = localDate.format(DateTimeFormatter.ofPattern(INT_DATE_PATTERN));
        return Integer.valueOf(dateStr);
    }

    public static Long secondsToStartOfTomorrow(ZoneId zoneId) {
        Instant nowInstant = Instant.now();
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(nowInstant, zoneId).plusDays(1);
        LocalDateTime localDateTime = zonedDateTime.toLocalDate().atStartOfDay();
        Instant tomorrowInstant = ZonedDateTime.of(localDateTime, zoneId).toInstant();
        return tomorrowInstant.minusMillis(nowInstant.toEpochMilli()).getEpochSecond();
    }

    public static Instant startTsOfTomorrow(ZoneId zoneId) {
        ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);
        return ZonedDateTime.of(zonedDateTime.plusDays(1).toLocalDate().atStartOfDay(), zoneId).toInstant();
    }

//    public static long durationWithDays(Integer first, Integer second) {
//        LocalDate firstDate = LocalDate.of(DateUtil.getYearFromDateInt(first), DateUtil.getMonthFromDateInt(first), DateUtil.getDayFromDateInt(first));
//        LocalDate secondDate = LocalDate.of(DateUtil.getYearFromDateInt(second), DateUtil.getMonthFromDateInt(second), DateUtil.getDayFromDateInt(second));
//        return firstDate.toEpochDay()- secondDate.toEpochDay();
//    }

    public static Date convertToDate(Integer date, ZoneId zoneId, String pattern, LocalTime localTime) {
        LocalDate localDate = LocalDate.parse(String.valueOf(date), DateTimeFormatter.ofPattern(pattern));
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, localTime, zoneId);
        return Date.from(zonedDateTime.toInstant());
    }

    public static ZoneId getAsiaShanghai() {
        return ZoneId.of(TIMEZONE_ASIN_SHANGHAI);
    }

    public static Date convertToDate(LocalDateTime localDateTime, String zoneIdStr) {
        ZoneId zoneId = ZoneId.of(zoneIdStr);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
        Instant instant = zonedDateTime.toInstant();
        Date date = Date.from(instant);
        return date;
    }

    public static Long convertToLongDateTime(String dateStrWithOutZone) {
        LocalDateTime localDateTime = LocalDateTime.parse(dateStrWithOutZone, DateTimeFormatter.ofPattern(formatterDateTimeStr));
        String dateStr = localDateTime.format(DateTimeFormatter.ofPattern(formatterIntStr));
        return Long.valueOf(dateStr);
    }

    /**
     * 通过某年的第几周获取该周第一天的日期，其中 weekCycle 形如 201901 表示2019年第一周，
     * firstDayOfWeek 表示一周是从哪个星期开始的，它的范围是 1 ～ 7 表示 周一到周日
     * */
    public static ZonedDateTime generateFistDayByWeekCycle(Integer weekCycle, String zoneId, Integer firstDayOfWeek) {
        int year = weekCycle / 100;
        int week = weekCycle % 100;
        ZonedDateTime firstDayOfYear = ZonedDateTime.of(year, 1, 1, 0,0,0,0,ZoneId.of(zoneId));
        ZonedDateTime firstWeekFirstDay = firstDayOfYear.with(ChronoField.DAY_OF_WEEK, firstDayOfWeek);
        return firstWeekFirstDay.plusWeeks(week - 1);
    }

    /**
     * 通过某年的第几周获取该周最后天的日期，其中 weekCycle 形如 201901 表示2019年第一周，
     * firstDayOfWeek 表示一周是从哪个星期开始的，它的范围是 1 ～ 7 表示 周一到周日
     * */
    public static ZonedDateTime generateLastDayByWeekCycle(Integer weekCycle, String zoneId, Integer firstDayOfWeek) {
        ZonedDateTime firstDay = generateFistDayByWeekCycle(weekCycle, zoneId, firstDayOfWeek);
        LocalDate localDate = firstDay.plusDays(6).toLocalDate();
        LocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.MAX);
        return ZonedDateTime.of(localDateTime, ZoneId.of(zoneId));
    }

    /**
     * 获取当天的最后时间
     * */
    public static ZonedDateTime todayEnd(String zoneId) {
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of(zoneId));
        return ZonedDateTime.of(now.toLocalDate(), LocalTime.MAX, ZoneId.of(zoneId));
    }

    public static ZonedDateTime endOfTheDay(ZonedDateTime zonedDateTime) {
        return ZonedDateTime.of(zonedDateTime.toLocalDate(), LocalTime.MAX, zonedDateTime.getZone());
    }

    public static List<ZonedDateTime> generateDateListByRange(ZonedDateTime start, ZonedDateTime end) {
        ZonedDateTime index = start;
        List<ZonedDateTime> dateList = Lists.newArrayList();
        while (index.compareTo(end) <= 0) {
            dateList.add(index);
            index = index.plusDays(1L);
        }
        return dateList;
    }

    /**
     * 获取俩个时间点间所有的月份
     * 2018年11月 到 2019年6月 返回 [201811, 201812, 201901, 201902, 201903, 201904, 201905, 201906]
     * 201901 表示2019年1月份
     * @param startDateTime 开始时间
     * @param endDateTime 结尾时间
     * @return
     */
    public static List<Integer> generateYearMonthRange(ZonedDateTime startDateTime, ZonedDateTime endDateTime) {
        int year = startDateTime.getYear();
        int monthValue = startDateTime.getMonthValue();

        int endYear = endDateTime.getYear();
        int endMonthValue = endDateTime.getMonthValue();
        Integer endYearMonth = endYear * 100 + endMonthValue;

        int yearIndex = year;
        int monthValueIndex = monthValue;
        Integer yearMonthIndex = year * 100 + monthValue;
        List<Integer> yearMonthRange = Lists.newArrayList();
        while (yearMonthIndex <= endYearMonth) {
            yearMonthRange.add(yearMonthIndex);
            if (monthValueIndex < 12) {
                monthValueIndex += 1;
            } else {
                monthValueIndex = 1;
                yearIndex += 1;
            }
            yearMonthIndex = yearIndex * 100 + monthValueIndex;
        }
        return yearMonthRange;
    }

    public static long intervalHours(ZonedDateTime zonedDateTime, ZonedDateTime compareTo){
        return Duration.between(zonedDateTime, compareTo).toHours();
    }

    /**
     * 求两个时间的间隔天数 to - from
     * */
    public static long intervalDays(ZonedDateTime from, ZonedDateTime to) {
        return Duration.between(from, to).toDays();
    }

    public static ZonedDateTime getFirstDayOfMonth(Date date, String zoneId) {
        ZonedDateTime dateTime = ZonedDateUtil.convertDate(date, zoneId);
        int dayOfMonth = dateTime.getDayOfMonth();
        return dateTime.minusDays(dayOfMonth - 1);
    }

    public static ZonedDateTime getFirstDayOfMonth(ZonedDateTime zonedDateTime) {
        int dayOfMonth = zonedDateTime.getDayOfMonth();
        return zonedDateTime.minusDays(dayOfMonth - 1);
    }

    /**
     * 将形如 "yyyyMMddHH" 转换成 ZonedDateTime类型
     * @param dateInt
     * @param zoneId
     * @return yyyy-MM-dd 00:00:00
     */
    public static Date convertDateIntHourToZoneDate(Integer dateInt, String zoneId) {
        String dateStr = String.valueOf(dateInt);
        String hStr = dateStr.substring(8,10);
        String[] arrays = {dateStr.substring(0,4), dateStr.substring(4,6), dateStr.substring(6,8)};
        dateStr = StringUtils.join(arrays, '-');
        dateStr = new StringBuilder(dateStr.trim()).append("T").append(hStr)
                .append(":00:00").toString();
        return Date.from(ZonedDateUtil.getZonedDateTime(dateStr, zoneId).toInstant());
    }

    /**
     * 将一个时间段，按天分割成时间段
     * @param cycleNum 平分的天数
     * */
    public static List<CycleTimeVo> getCycleList(int cycleNum,Date startParse,Date endParse,String zoneId) {
        logger.info("getCycleList start={}","统计的时间段为：从"+startParse+"到"+endParse);
        Long endLong = endParse.getTime();
        Long startLong = startParse.getTime();
        //获取时间差
        int daysBetweenNum = daysBetween(startParse, endParse);
        int cycleForNum = daysBetweenNum % cycleNum == 0 ? (daysBetweenNum / cycleNum) : (daysBetweenNum / cycleNum) + 1;
        logger.info("两日期间相隔的天数为：" + daysBetweenNum);
        logger.info("周期选择是：" + cycleNum + "根据周期, 则切割出来的周期存在个数：" + cycleForNum);
        Long calculationLong = startLong;
        List<CycleTimeVo> CycleTimeList=new ArrayList();
        for (int i = 1; i <= cycleForNum; i++) {
            Date startDate = new Date(calculationLong);
            Long startStrLong = startDate.getTime();
            Long cycleLong = cycleNum * 86400000L;
            calculationLong = startStrLong + cycleLong;
            Date endDate = endParse;
            if (calculationLong <= endLong) {
                endDate = new Date(calculationLong);
            }
            logger.info("起始:" + formatDate(startDate,dayFormatterStr,zoneId) + "结束：" + formatDate(endDate,dayFormatterStr,zoneId));
            CycleTimeVo cycleTimeVo=new CycleTimeVo();
            cycleTimeVo.setStartDate(startDate);
            cycleTimeVo.setEndDate(endDate);
            CycleTimeList.add(cycleTimeVo);
        }
        logger.info("CycleTimeList listStr={}","周期list："+CycleTimeList.toString());
        return CycleTimeList;
    }

    /**
     * 内部类，用于返回切割的时间数据
     * */
    @Data
    public static class CycleTimeVo{
        //开始时间
        private Date startDate;
        //结束时间
        private Date endDate;
    }

    /**
     * 获取两时间段之间的天数
     * @param startDate
     * @param endDate
     * */
    public static int daysBetween(Date startDate, Date endDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(endDate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

    /***
     * 获取int型站点日期的int型UTC开始小时
     * @param localIntDate
     * @param zoneId
     * @return
     */
    public static int toStartHoursOfLocalIntDate(int localIntDate, String zoneId){
        ZonedDateTime zonedDateTime = ZonedDateUtil.convertDateIntToZoneDate(localIntDate, zoneId);
        ZonedDateTime of = ZonedDateTime.of(zonedDateTime.toLocalDate(), LocalTime.MIN, zonedDateTime.getZone());
        return Integer.valueOf(ZonedDateUtil.formatDate(convertToDate(of), ZonedDateUtil.HOUR_FORMATTER_STR, ZonedDateUtil.TIMEZONE_UTC));
    }

    public static int toEndHoursOfLocalIntDate(int localIntDate, String zoneId){
        ZonedDateTime zonedDateTime = ZonedDateUtil.convertDateIntToZoneDate(localIntDate, zoneId);
        ZonedDateTime of = ZonedDateTime.of(zonedDateTime.toLocalDate(), LocalTime.MAX, zonedDateTime.getZone());
        return Integer.valueOf(ZonedDateUtil.formatDate(convertToDate(of), ZonedDateUtil.HOUR_FORMATTER_STR, ZonedDateUtil.TIMEZONE_UTC));
    }

    public static int toNextStartHoursOfLocalIntDate(int localIntDate, String zoneId){
        ZonedDateTime zonedDateTime = ZonedDateUtil.convertDateIntToZoneDate(localIntDate, zoneId).plusDays(1);
        ZonedDateTime of = ZonedDateTime.of(zonedDateTime.toLocalDate(), LocalTime.MIN, zonedDateTime.getZone());
        return Integer.valueOf(ZonedDateUtil.formatDate(convertToDate(of), ZonedDateUtil.HOUR_FORMATTER_STR, ZonedDateUtil.TIMEZONE_UTC));
    }

    public static long intervalInAbsDays(ZonedDateTime zonedDateTime) {
        ZonedDateTime compareTo = ZonedDateTime.now();
        return Duration.between(zonedDateTime, compareTo).abs().toDays();
    }

    public static Date convertStrToDate(String dateStr, String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException e) {
            logger.error("parse UTC date String to Date failed: ", e);
        }
        return null;
    }

    public static String convertZoneTimeToStr(ZonedDateTime zonedDateTime, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return zonedDateTime.format(formatter);
    }


    /**
     * 获取本周的时间范围
     * @return 返回长度为2的字符串集合，如：[2017-10-30, 2017-11-05]
     */
    public static String getCurrentWeekStart(String zoneId) {
        ZonedDateTime dateTime = ZonedDateUtil.convertDate(new Date(),zoneId);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周之内的第一天
        calendar.setTime(ZonedDateUtil.convertToDate(dateTime));
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        String monday = dateFormat.format(calendar.getTime());
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return monday;
    }

    /**
     * 获取本月的时间范围
     * @return 返回长度为2的字符串集合，如：[2017-11-01, 2017-11-30]
     */
    public static String getCurrentMonthStart(String zoneId) {
        ZonedDateTime dateTime = ZonedDateUtil.convertDate(new Date(),zoneId);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(ZonedDateUtil.convertToDate(dateTime));
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        String firstDayOfMonth = dateFormat.format(calendar.getTime());
        return firstDayOfMonth;
    }

    /**
     * 将13位时间戳转为date
     * @param startDate
     * @param zoneId
     * @return
     */
    public static Date timestampToDate(String startDate, String zoneId) {
        ZonedDateTime zonedDateTime = Instant.ofEpochMilli(Long.parseLong(startDate)).atZone(ZoneId.of(zoneId));
        Date dateTime = ZonedDateUtil.convertToDate(zonedDateTime);
        return dateTime;
    }

    /**
     * 获取日期在一年中所属的周 如：2021W21
     * @param date
     * @return
     */
    public static String getWeek(String date) {
        LocalDate time = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int week = time.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
        int weekYear = time.get(IsoFields.WEEK_BASED_YEAR);
        return weekYear + "W" + (week < 10 ? "0" + week : week);
    }

    /**
     * 获取月份 如：202105
     * @param date
     * @return
     */
    public static String getMonth(String date) {
        LocalDate time = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int month = time.getMonthValue();
        int year = time.getYear();
        return year+(month < 10 ? "0" + month : String.valueOf(month));
    }

    /**
     * 如：2021-05-01 to 202105
     * @param date
     * @return
     */
    public static Integer convertStrgDateToDateInt(String date) {
        return Integer.parseInt(date.replaceAll("-", ""));
    }

    /**
     *  如：20210501 to 2021-05-01
     * @param
     * @return
     */

    public static String convertDateIntToStrDate(Integer dateInt) {
        String dateStr = String.valueOf(dateInt);
        String[] arrays = {dateStr.substring(0,4), dateStr.substring(4,6), dateStr.substring(6,8)};
        return dateStr = StringUtils.join(arrays, '-');
    }

    /**
     * 获取日期在一年中所属的周 如：202121
     * @param date
     * @return
     */
    public static Integer getIntYearWeek(String date) {
        LocalDate time = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int week = time.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
        int Year = time.get(IsoFields.WEEK_BASED_YEAR);
        return Year *100 + week ;
    }

    /**
     * 获取月份 如：202105
     * @param date
     * @return
     */
    public static Integer getIntYearMonth(String date) {
        LocalDate time = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int month = time.getMonthValue();
        int year = time.getYear();
        return year *100 + month ;
    }
    /**
     *  如：202105 to 2021w05
     * @param
     * @return
     */
    public static String toStrWeek(Integer week){
        String dateStr = String.valueOf(week);
        String[] arrays = {dateStr.substring(0,4), dateStr.substring(4,6)};
        return dateStr = StringUtils.join(arrays, 'W');
    }


}
